const getCookie=(name) =>{
    const cookies = document.cookie.split('; ');
    for (const cookie of cookies) {
      const [cookieName, cookieValue] = cookie.split('=');
      if (cookieName === name) {
        return decodeURIComponent(cookieValue); // 解码（防止特殊字符）
      }
    }
    return null; // 未找到返回 null
}

class WebSocketChat {
    constructor(url,messageMapper, userId = null) {
        this.userId = userId; // 用户ID
        this.url = `ws://127.0.0.1:8001/chat_socket/${url}/${this.userId}`; // WebSocket 服务器地址
        this.socket = null; // WebSocket 实例
        this.isConnected = false; // 连接状态
        this.messageHandlers =messageMapper; // 消息处理器映射表
        this.defaultHandler = null; // 默认消息处理器
        this.pingInterval = 25 * 1000; // 25秒心跳
        this.reconnectTimeout = 40 * 1000; // 35秒无响应则重连
        this.lastMessageTimestamp = Date.now(); // 上次收到消息的时间
        this.reconnectTimer = null; // 重连计时器
        this.pingTimer = null; // 心跳计时器
        this.onConnectCallbacks = []; // 连接成功回调
    }

      
    // 使用示例
    /**
     * 连接 WebSocket
     * @returns {Promise<void>}
     */
    connect() {
        return new Promise((resolve, reject) => {
            if (this.isConnected) {
                // console.log("WebSocket is already connected.");
                resolve();
                return;
            }
       
            this.socket = new WebSocket(this.url);
            
            this.socket.onopen = () => {
                this.isConnected = true;
                this.lastMessageTimestamp = Date.now();
                this.startPing();
                this.startReconnectTimer();
                this.onConnectCallbacks.forEach(cb => cb(this));
                resolve();
            };

            this.socket.onerror = (error) => {
                console.error("WebSocket error:", error);
                this.isConnected = false;
                reject(error);
            };

            this.socket.onclose = () => {
                this.isConnected = false;
                this.stopPing();
                this.stopReconnectTimer();
                console.log("WebSocket disconnected.");
            };

            this.socket.onmessage = (event) => {
                this.lastMessageTimestamp = Date.now();
                try {
                    const message = JSON.parse(event.data);
                    const { type, data} = message;
                    const handler = this.messageHandlers[type];
                    if (handler) {
                        // 注入socket实现可以执行soket的sendMessage
                        handler(data, this); 
                    } else if (this.defaultHandler) {
                        this.defaultHandler(message, this);
                    } else {
                        // console.warn(`No handler for message type: ${type}`);
                    }
                } catch (error) {
                    // console.error("Failed to parse message:", error);
                }
            };
        });
    }


    onMessage(type, handler) {
        this.messageHandlers[type] = handler;
    }


    onDefaultMessage(handler) {
        this.defaultHandler = handler;
    }

    /**
     * 发送消息
     * @param {string} type - 消息类型
     * @param {object} data - 消息数据
     */
     sendMessage(type, data, maxRetries = 3, retryDelay = 1000,onSuccess = null,onFailure=null,meta=null) {
    // type是handler标记,data是数据包括信息和数据类型
    // 对于消息
    //  message_type: 
    // content: 
    // sender_id: 
    // room_id: 
    // receiver_id: 
    
    // 由于消息一般是直接实时,先存储,在判断处理,可拓展失败信息
    if (typeof onSuccess === 'function') {
          onSuccess();
    }
    if (!this.isConnected || !this.socket) {
        // console.error("WebSocket not connected. Attempting to reconnect...");
        this.reconnect();
        return;
    }
    const attemptSend = (retryCount = 0) => {
        try {
            const message = JSON.stringify({
                type: type,
                data: data
            });
            
            this.socket.send(message);
            // 如果提供了成功回调，调用它
        } catch (error) {
            // console.error(`Send attempt ${retryCount + 1} failed:`, error);
            if (retryCount < maxRetries) {
                // console.log(`Retrying in ${retryDelay}ms... (Attempt ${retryCount + 2}/${maxRetries})`);
                setTimeout(() => {
                    // 检查连接状态，如果未连接则尝试重新连接
                    if (!this.isConnected || !this.socket) {
                        this.reconnect();
                    }
                    attemptSend(retryCount + 1);
                }, retryDelay);
            } else {
                if (typeof onFailure === 'function') { 
                    onFailure()
                }
                // 可以在这里添加失败后的回调或处理逻辑
            }
        }
    };

    attemptSend();
}

    /**
     * 关闭连接
     */
    disconnect() {
        if (this.socket) {
            this.socket.close();
            this.isConnected = false;
        }
    }

    /**
     * 启动心跳检测
     */
    startPing() {
        this.pingTimer = setInterval(() => {
            if (this.isConnected) {
                this.sendMessage("ping", { message: "heartbeat" });
            }
        }, this.pingInterval);
    }

    /**
     * 停止心跳检测
     */
    stopPing() {
        if (this.pingTimer) {
            clearInterval(this.pingTimer);
            this.pingTimer = null;
        }
    }

    /**
     * 启动重连监控
     */
    startReconnectTimer() {
        this.reconnectTimer = setInterval(() => {
            const now = Date.now();
            if (now - this.lastMessageTimestamp > this.reconnectTimeout) {
                console.warn("No message received in 30s. Reconnecting...");
                this.reconnect();
            }
        }, 5000); // 每 5 秒检查一次
    }

    /**
     * 停止重连监控
     */
    stopReconnectTimer() {
        if (this.reconnectTimer) {
            clearInterval(this.reconnectTimer);
            this.reconnectTimer = null;
        }
    }

    /**
     * 尝试重新连接
     */
    reconnect() {
        this.disconnect();
        this.connect().catch((error) => {
            console.error("Reconnect failed:", error);
        });
    }

    /**
     * 获取 WebSocket 实例（谨慎使用）
     * @returns {WebSocket | null}
     */
    getSocket() {
        return this.socket;
    }

    /**
     * 注册连接成功回调
     * @param {function} callback - 回调函数，接收 WebSocketChat 实例
     */
    onConnect(callback) {
        this.onConnectCallbacks.push(callback);
        if (this.isConnected) {
            callback(this);
        }
    }
}

export default WebSocketChat;